package net.lastcoder.ifserver;

import net.lastcoder.ifserver.command.CommandManager;
import net.lastcoder.ifserver.game.GameManager;
import net.lastcoder.ifserver.script.ScriptManage;
import net.lastcoder.ifserver.web.WebsocketManager;
import net.lastcoder.ifserver.plugin.PluginManager;
import net.lastcoder.ifserver.util.TaskEngine;
import net.lastcoder.ifserver.util.Version;

import org.apache.log4j.Level;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.HashMap;
import java.util.Scanner;
import java.util.TimerTask;

/**ifserver，注意必须配置config路径
 * auth: WenYF
 * date: 2016/9/30
 */
public class Server {
    private static final Logger Log = LoggerFactory.getLogger(Server.class);
    
    private static Server instance;
    
    private String env = "debug";
    public long startTime = 0;
    
    public static Server getInstance() {
        return instance;
    }

    private PluginManager pluginManager;
    private CommandManager commandManager;
    private WebsocketManager websocketManager;
    private HashMap<String, Object> attributes;
    private String homePath;
    private boolean isStopping;
    public Server() {
        instance = this;
        attributes = new HashMap<>();

        File file = new File("");
        homePath = file.getAbsolutePath();
        if (homePath.endsWith("bin")) {
            homePath = file.getAbsolutePath() + "/.."; 
        }
        Log.info("home = " + homePath);

        // 必须设置Home目录
        org.apache.log4j.LogManager.getRootLogger().setLevel(Level.toLevel("debug"));

        Log.debug("developmentMode = " + Boolean.getBoolean("developmentMode"));

        Runtime.getRuntime().addShutdownHook(new ShutdownHookThread());

        if (!env.equals("prod")) {
            //TaskEngine.getInstance().schedule(new Terminator(), 1000, 1000);
            new Thread(new Terminator(), "terminator").start();
        }

        if (Boolean.getBoolean("inide")) {
            ScriptManage.getInstance().setDir(new File(homePath + "/src/scripts").getAbsolutePath());
            pluginManager = new PluginManager(new File(homePath + "/target/ifserver", "plugins"));
        }
        else {
            ScriptManage.getInstance().setDir(new File(homePath, "/scripts").getAbsolutePath());
            pluginManager = new PluginManager(new File(homePath, "plugins"));
        }
        
        websocketManager = WebsocketManager.getInstance();
        commandManager = CommandManager.getInstance();
        
        start();

        isStopping = false;
        startTime = System.currentTimeMillis();
    }

    public void start() {
        websocketManager.startServer();
        pluginManager.start();
        GameManager.getInstance().start();
    }



    private class ShutdownHookThread extends Thread {

        /**
         * <p>Logs the server shutdown.</p>
         */
        @Override
        public void run() {
            shutdownServer();
            Log.info("Server halted");
            System.err.println("Server halted");
        }
    }

    private void shutdownServer() {
        Log.info("ifserver stopping...");
        isStopping = true;
        
        // 先关闭定时任务
        TaskEngine.getInstance().shutdown();

        // 关闭插件，必须在module之前
        pluginManager.shutdown();

        // 关闭连接
        websocketManager.stopServer();
        
        Log.info("ifserver stopped");
    }

    /**是否正在关闭，给关闭中的插件和模块可能需要用到
     * @return
     */
    public boolean isStopping() {
        return isStopping;
    }


    /**
     * 控制台输入
     */
    private class Terminator extends TimerTask {
        //private BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
        private Scanner scanner = new Scanner(System.in);
        @Override
        public void run() {
            while (true) {
                try {
                    if (scanner.hasNextLine()) {
                        String line = scanner.nextLine();
                        System.out.println(commandManager.processCommand(line));
                    }
                } catch (IllegalStateException ioe) {
                    ioe.printStackTrace();
                    System.err.println("error input, " + ioe.getMessage());
                } catch (Exception e) {
                    e.printStackTrace();
                    System.err.println("process error : " + e.getMessage());
                }
            }
        }
    }

    /**
     * @return 得到服务器启动时间
     */
    public long getStartTime() {
        return startTime;
    }
    
    public Version getVersion() {
        Version version = new Version(0, 0, 1, Version.ReleaseStatus.Beta, 1);
        return version;
    }

    public boolean isSetupMode() {
        return true;
    }
    
    public PluginManager getPluginManager() {
        return pluginManager;
    }


    /**
     * 直接启动，在ide中使用，实际部署环境，用ServerStart启动，也就是bin下面的额脚本
     * 
     * @param args
     */
    public static void main(String[] args) {
        System.setProperty("inide", "true");
        new Server();
    }
}
